package com.qq.connect.oauth;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.jbase.oauth.QqConfig;

import com.qq.connect.QQConnect;
import com.qq.connect.QQConnectException;
import com.qq.connect.javabeans.QqAccessToken;
import com.qq.connect.utils.RandomStatusGenerator;
import com.qq.connect.utils.http.PostParameter;

public class Oauth extends QQConnect {
	private static final long serialVersionUID = -7860508274941797293L;

	private String[] extractionAuthCodeFromUrl(String url) throws QQConnectException {
		if (url == null) {
			throw new QQConnectException("you pass a null String object");
		}
		Matcher m = Pattern.compile("code=(\\w+)&state=(\\w+)&?").matcher(url);
		String authCode = "";
		String state = "";
		if (m.find()) {
			authCode = m.group(1);
			state = m.group(2);
		}

		return new String[] { authCode, state };
	}

	public QqAccessToken getAccessTokenByRequest(ServletRequest request) throws QQConnectException {
		String queryString = ((HttpServletRequest) request).getQueryString();
		if (queryString == null) {
			return new QqAccessToken();
		}
		String state = (String) ((HttpServletRequest) request).getSession().getAttribute("qq_connect_state");
		if ((state == null) || (state.equals(""))) {
			return new QqAccessToken();
		}

		String[] authCodeAndState = extractionAuthCodeFromUrl(queryString);
		String returnState = authCodeAndState[1];
		String returnAuthCode = authCodeAndState[0];

		QqAccessToken accessTokenObj = null;

		if ((returnState.equals("")) || (returnAuthCode.equals(""))) {
			accessTokenObj = new QqAccessToken();

		} else if (!state.equals(returnState)) {
			accessTokenObj = new QqAccessToken();
		} else {
			accessTokenObj = new QqAccessToken(this.client.post(QqConfig.getValue("accessTokenURL"),
					new PostParameter[] { new PostParameter("client_id", QqConfig.getValue("app_ID")),
							new PostParameter("client_secret", QqConfig.getValue("app_KEY")),
							new PostParameter("grant_type", "authorization_code"),
							new PostParameter("code", returnAuthCode),
							new PostParameter("redirect_uri", QqConfig.getValue("redirect_URI")) },
					Boolean.valueOf(false)));
		}

		return accessTokenObj;
	}

	/**
	 * @deprecated
	 */
	public QqAccessToken getAccessTokenByQueryString(String queryString, String state) throws QQConnectException {
		if (queryString == null) {
			return new QqAccessToken();
		}

		String[] authCodeAndState = extractionAuthCodeFromUrl(queryString);
		String returnState = authCodeAndState[1];
		String returnAuthCode = authCodeAndState[0];

		QqAccessToken accessTokenObj = null;

		if ((returnState.equals("")) || (returnAuthCode.equals(""))) {
			accessTokenObj = new QqAccessToken();

		} else if (!state.equals(returnState)) {
			accessTokenObj = new QqAccessToken();
		} else {
			accessTokenObj = new QqAccessToken(this.client.post(QqConfig.getValue("accessTokenURL"),
					new PostParameter[] { new PostParameter("client_id", QqConfig.getValue("app_ID")),
							new PostParameter("client_secret", QqConfig.getValue("app_KEY")),
							new PostParameter("grant_type", "authorization_code"),
							new PostParameter("code", returnAuthCode),
							new PostParameter("redirect_uri", QqConfig.getValue("redirect_URI")) },
					Boolean.valueOf(false)));
		}

		return accessTokenObj;
	}

	/**
	 * @deprecated
	 */
	public String getAuthorizeURL(String scope, String state) throws QQConnectException {
		return QqConfig.getValue("authorizeURL").trim() + "?client_id="
				+ QqConfig.getValue("app_ID").trim() + "&redirect_uri="
				+ QqConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state
				+ "&scope=" + scope;
	}

	/**
	 * @deprecated
	 */
	public String getAuthorizeURL(String state) throws QQConnectException {
		String scope = QqConfig.getValue("scope");
		if ((scope != null) && (!scope.equals(""))) {
			return getAuthorizeURL("code", state, scope);
		}
		return QqConfig.getValue("authorizeURL").trim() + "?client_id="
				+ QqConfig.getValue("app_ID").trim() + "&redirect_uri="
				+ QqConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state;
	}

	/**
	 * @deprecated
	 */
	public String getAuthorizeURLByScope(String scope, ServletRequest request) throws QQConnectException {
		String state = RandomStatusGenerator.getUniqueState();
		((HttpServletRequest) request).setAttribute("qq_connect_state", state);

		return QqConfig.getValue("authorizeURL").trim() + "?client_id="
				+ QqConfig.getValue("app_ID").trim() + "&redirect_uri="
				+ QqConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state
				+ "&scope=" + scope;
	}

	public String getAuthorizeURL(ServletRequest request) throws QQConnectException {
		String state = RandomStatusGenerator.getUniqueState();
		((HttpServletRequest) request).getSession().setAttribute("qq_connect_state", state);
		String scope = QqConfig.getValue("scope");
		if ((scope != null) && (!scope.equals(""))) {
			return getAuthorizeURL("code", state, scope);
		}
		return QqConfig.getValue("authorizeURL").trim() + "?client_id="
				+ QqConfig.getValue("app_ID").trim() + "&redirect_uri="
				+ QqConfig.getValue("redirect_URI").trim() + "&response_type=" + "code" + "&state=" + state;
	}

	/**
	 * @deprecated
	 */
	public String getAuthorizeURL(String response_type, String state, String scope) throws QQConnectException {
		return QqConfig.getValue("authorizeURL").trim() + "?client_id="
				+ QqConfig.getValue("app_ID").trim() + "&redirect_uri="
				+ QqConfig.getValue("redirect_URI").trim() + "&response_type=" + response_type + "&state="
				+ state + "&scope=" + scope;
	}
}
